A ggplot2 demo
library(ggplot2)
library(grid)
dt <- data.frame( num = 1:10,
ab = rep(c("a", "b"), each = 5),
xy = rep(c("x", "y"), length.out = 10),
d = 1:10 / 10 )
p <- ggplot(dt, aes(x = num, y = num, fill = ab, color = xy, size = num, alpha = d)) +
facet_grid(ab ~ xy, scales = "free", switch = "both") +
geom_point()
p <- p +
guides(alpha = guide_legend(title = "Alpha"),
size = guide_legend(title = "Size"),
color = guide_legend(title = "Color"),
fill = guide_legend(title = "Fill")
) +
labs(title = "title",
subtitle = "subtitle",
caption = "caption",
# tag = "tag",
x = "xlab.1",
y = "ylab.1"
) +
scale_x_continuous(sec.axis = dup_axis(name = "xlab.2")) +
scale_y_continuous(sec.axis = dup_axis(name = "ylab.2"))
in debug style
p <- p +
theme(
legend.background = element_rect(fill = "grey", color = "black"),
legend.box.background = element_rect(fill = "lightblue", color = "red"),
legend.key = element_rect(fill = "yellow", color = "green"),
legend.text = element_text(debug = TRUE),
legend.title = element_text(debug = TRUE)
) +
theme(
axis.title = element_text(debug = TRUE),
axis.text = element_text(debug = TRUE),
axis.line = element_line(color = "red"),
) +
theme(
strip.text = element_text(debug = TRUE)
) +
theme(
plot.margin = margin(0,0,0,0, "pt"),
plot.background = element_rect(fill = "pink"),
plot.title = element_text(debug = TRUE, margin = margin(0,0,0,0, "line")),
plot.subtitle = element_text(debug = TRUE, margin = margin(0,0,0,0, "line")),
plot.caption = element_text(debug = TRUE, margin = margin(0,0,0,0, "line")),
plot.tag = element_text(debug = TRUE)
) +
theme(
panel.background = element_rect(fill = "orange"),
)
p + theme(
axis.title = element_text(size = 20, margin = margin(1,1,1,1,"line"))
# axis.title.x = element_text(),
# axis.title.x.top = element_text(),
# axis.title.x.bottom = element_text(),
# axis.title.y = element_text(),
# axis.title.y.left = element_text(),
# axis.title.y.right = element_text(),
)
axis.title.*, axis.title.*.* do not inherit element_text(margin) from axis.title.axis.title.x and axis.title.y have called element_text(margin) alreadyaxis.title and axis.text in size unit(11 / 4, "pt").
p + theme(
# axis.title = element_text(),
axis.title.x = element_text(size = 20, margin = margin(1,1,1,1,"line")),
# axis.title.x.top = element_text(),
# axis.title.x.bottom = element_text(),
axis.title.y = element_text(size = 20, margin = margin(1,1,1,1,"line"))
# axis.title.y.left = element_text(),
# axis.title.y.right = element_text(),
)
axis.title.x.top dose not inherit element_text(margin) from axis.title.xaxis.title.y.right dose not inherit that from axis.title.y.
p + theme(
axis.title = element_text(size = 20),
axis.title.x = element_text(margin = margin(1,1,1,1,"line")),
axis.title.x.top = element_text(margin = margin(1,1,1,1,"line")),
# axis.title.x.bottom = element_text(),
axis.title.y = element_text(margin = margin(1,1,1,1,"line")),
# axis.title.y.left = element_text(),
axis.title.y.right = element_text(margin = margin(1,1,1,1,"line"))
)
element_text(margin), these axis.title.** have to be set explicitly
p + theme(
axis.text = element_text(size = 20, margin = margin(1,1,1,1,"line"))
# axis.text.x = element_text(),
# axis.text.x.top = element_text(),
# axis.text.x.bottom = element_text(),
# axis.text.y = element_text(),
# axis.text.y.left = element_text(),
# axis.text.y.right = element_text()
)
axis.title
p + theme(
axis.text = element_text(size = 20),
# axis.text.x = element_text(),
axis.text.x.top = element_text(vjust = 1),
axis.text.x.bottom = element_text(vjust = 0),
# axis.text.y = element_text(),
axis.text.y.left = element_text(hjust = 0),
axis.text.y.right = element_text(hjust = 1)
)
axis.text and axit.ticks, which due to default theme with default size unit(0.8 * 11 / 4, "pt").
axis.ticks = element_line(size) only controls the length along axes, and does not effect the size of plot.
p + theme(
axis.ticks = element_line(size = 10)
# axis.ticks.x = element_line(),
# axis.ticks.x.top = element_line(),
# axis.ticks.x.bottom = element_line(),
# axis.ticks.y = element_line(),
# axis.ticks.y.left = element_line(),
# axis.ticks.y.right = element_line()
)
p + theme(
axis.ticks = element_line(size = 100)
# axis.ticks.x = element_line(),
# axis.ticks.x.top = element_line(),
# axis.ticks.x.bottom = element_line(),
# axis.ticks.y = element_line(),
# axis.ticks.y.left = element_line(),
# axis.ticks.y.right = element_line()
)
To control the length vertically, you need to change axis.ticks.length.
p + theme(
axis.ticks.length = unit(0.5,"cm") # default unit(11 / 4, "pt")
# axis.ticks.length.x = NULL,
# axis.ticks.length.x.top = NULL,
# axis.ticks.length.x.bottom = NULL,
# axis.ticks.length.y = NULL,
# axis.ticks.length.y.left = NULL,
# axis.ticks.length.y.right = NULL
)
axis.line has no effect on plot size as well.
gt1 <- ggplotGrob(p)
gt1$heights
## [1] 0pt 0cm 1grobheight 1grobheight
## [5] 1grobheight 0.46152783900704cm 1null 5.5pt
## [9] 1null 0.59683986336016cm 0.46152783900704cm 1grobheight
## [13] 1grobheight 0pt 0pt
p2 <- p + theme(
axis.line = element_line(size = 10, linetype = 'dashed')
# axis.line.x = element_line(),
# axis.line.x.top = element_line(),
# axis.line.x.bottom = element_line(),
# axis.line.y = element_line(),
# axis.line.y.left = element_line(),
# axis.line.y.right = element_line()
)
gt2 <- ggplotGrob(p2)
gt2$heights
## [1] 0pt 0cm 1grobheight 1grobheight
## [5] 1grobheight 0.46152783900704cm 1null 5.5pt
## [9] 1null 0.59683986336016cm 0.46152783900704cm 1grobheight
## [13] 1grobheight 0pt 0pt
p2
p + theme(
strip.text = element_text(size = 20, margin = margin(1,1,1,1,"line")),
# strip.text.x = element_text(),
# strip.text.y = element_text()
)
strip.placement controls strips placing inside or outside axis.text grobs (including axis.text, axis.ticks and axis.line).
And strip.switch.pad.* only works for the outside strips, and controls the width of the gap between strips and axis.text grobs.
p + theme(strip.text = element_text(size = 20)) +
theme(
# strip.placement = NULL,
strip.placement.x = "outside",
strip.placement.y = NULL
) +
theme(
strip.switch.pad.grid = unit(1, "line"),
# strip.switch.pad.wrap = unit(1, "line") # for facet_wrap
)
p + facet_wrap(ab ~ xy) +
theme(strip.text = element_text(size = 20)) +
theme(
strip.placement = "outside",
strip.switch.pad.wrap = unit(1, "line")
)
ps.
labeller(.multi_line) can collapse strips of the same side.
p + facet_wrap(ab ~ xy,
labeller = labeller(.multi_line = F)) +
theme(strip.text = element_text(size = 20)) +
theme(
strip.placement = "outside",
strip.switch.pad.wrap = unit(1, "line")
)
Unfortunately, unlike the elements mentioned above, the size of panels are not certain.
The unit of the viewport of the panels are 1NULL, which means the size of the panels only calculate after the plot is drawn.
They’re determined by the size of the window you open or the device you save graphics.
You cannot control the size of panels by setting theme.
gt <- ggplotGrob(p)
layout <- gtable:::gtable_layout(gt)
grid:::grid.show.layout(layout)
But you can control the gap between each panels.
p + theme(
panel.spacing = unit(1, "line"),
# panel.spacing.x = NULL,
# panel.spacing.y = NULL
)
Default legend.position is right, and also support left, top, bottom and none.
p + theme(legend.position = "left")
p + theme(legend.position = "top")
p + theme(legend.position = "bottom")
p + theme(legend.position = "none")
legend.position also support a coordinate (two-element numeric vector).
A better practice is using in combination with legend.justification.
p + theme(
legend.position = c(0.25, 0),
legend.justification = c(0, 0) # default "center"
)
But Comparing to the default layout (left), the legend will no longer be apart of the plot grob tree when using legend.position in this way. The legend will not contribute to panel calculation (see panel size).
legend.box controls the arrangement of multiple legends.
legend.box.just controls the justification of each legend within the overall bounding box, when there are multiple legends.
#default
p + theme(legend.box = "vertical", legend.box.just = "left")
p + theme(legend.box = "vertical", legend.box.just = "right")
p + theme(legend.box = "horizontal", legend.box.just = "top")
p + theme(legend.box = "horizontal", legend.box.just = "bottom")
The spacing between the plotting area and the legend box.
See more example in legend.position, show how it effect in different conditions.
p + theme(legend.box.spacing = unit(2, "line"))
# default unit(11, "pt")
Margins around the full legend area.
p + theme(legend.box.margin = margin(2,2,2,2, "line"))
# default margin(0, 0, 0, 0, "cm")
The margin around each legend.
p + theme(legend.margin = margin(2,2,2,2, "line"))
# default margin(5.5, 5.5, 5.5, 5.5, "pt")
The spacing between legends.
legend.spacing.x controls the horizontal gaps between legend.title and legend.key, between legend.key and legend.text as well as between multi legends.
legend.spacing.y controls the vertical gaps between legend.title and legend.key, between legend.key and legend.text as well as between multi legends.
pl <- p + guides(
size = guide_legend(title = "Size", ncol = 3, byrow = TRUE),
alpha = guide_legend(title = "Alpha", ncol = 2)
)
pl + theme(
# legend.spacing = NULL, # default unit(11, "pt")
legend.spacing.x = unit(1, "line"),
legend.spacing.y = unit(2, "line")
)
pl + theme(
legend.spacing.x = unit(1, "line"),
legend.spacing.y = unit(2, "line"),
legend.box = "horizontal"
)
p + theme(
legend.title = element_text(size = 15, margin = margin(1,1,1,1, "line")),
legend.text = element_text(size = 15, margin = margin(1,1,1,1, "line"))
)
legend.key.size controls the size of legend keys.
p + theme(
legend.key.size = unit(3, "line") # default unit(1.2, "lines")
# legend.key.height = NULL,
# legend.key.width = NULL
)
legend.key.size only effect the box of legend keys instead of the symbol. To resize the symbol inside legend keys, you need to use guides.
example
p + guides(alpha = guide_legend(title = "Alpha", override.aes = list(size = 20) ))
p + theme(plot.margin = margin(1,1,1,1, "line"))
# default margin(5.5, 5.5, 5.5, 5.5, "pt")
p + theme(plot.title = element_text(margin = margin(1,1,1,1, "line")))
# default margin(b = 5.5, "pt")
p + theme(plot.subtitle = element_text(margin = margin(1,1,1,1, "line")))
# default margin(b = 5.5, "pt")
p + theme(plot.caption = element_text(margin = margin(1,1,1,1, "line")))
# default margin(t = 5.5, "pt")
p + labs(tag = "A")
# default margin(0, 0, 0, 0, "pt")
p + labs(tag = "A") + theme(plot.tag = element_text(margin = margin(1,1,1,1, "line")))
p + labs(tag = "A") +
theme(legend.position = "left")
p + labs(tag = "A") +
theme(legend.position = "top")
ggplot2::theme_grey
details
function (base_size = 11, base_family = "", base_line_size = base_size/22,
base_rect_size = base_size/22)
{
half_line <- base_size/2
theme(line = element_line(colour = "black", size = base_line_size,
linetype = 1, lineend = "butt"), rect = element_rect(fill = "white",
colour = "black", size = base_rect_size, linetype = 1),
text = element_text(family = base_family, face = "plain",
colour = "black", size = base_size, lineheight = 0.9,
hjust = 0.5, vjust = 0.5, angle = 0, margin = margin(),
debug = FALSE), axis.line = element_blank(), axis.line.x = NULL,
axis.line.y = NULL, axis.text = element_text(size = rel(0.8),
colour = "grey30"), axis.text.x = element_text(margin = margin(t = 0.8 *
half_line/2), vjust = 1), axis.text.x.top = element_text(margin = margin(b = 0.8 *
half_line/2), vjust = 0), axis.text.y = element_text(margin = margin(r = 0.8 *
half_line/2), hjust = 1), axis.text.y.right = element_text(margin = margin(l = 0.8 *
half_line/2), hjust = 0), axis.ticks = element_line(colour = "grey20"),
axis.ticks.length = unit(half_line/2, "pt"), axis.ticks.length.x = NULL,
axis.ticks.length.x.top = NULL, axis.ticks.length.x.bottom = NULL,
axis.ticks.length.y = NULL, axis.ticks.length.y.left = NULL,
axis.ticks.length.y.right = NULL, axis.title.x = element_text(margin = margin(t = half_line/2),
vjust = 1), axis.title.x.top = element_text(margin = margin(b = half_line/2),
vjust = 0), axis.title.y = element_text(angle = 90,
margin = margin(r = half_line/2), vjust = 1), axis.title.y.right = element_text(angle = -90,
margin = margin(l = half_line/2), vjust = 0), legend.background = element_rect(colour = NA),
legend.spacing = unit(2 * half_line, "pt"), legend.spacing.x = NULL,
legend.spacing.y = NULL, legend.margin = margin(half_line,
half_line, half_line, half_line), legend.key = element_rect(fill = "grey95",
colour = "white"), legend.key.size = unit(1.2, "lines"),
legend.key.height = NULL, legend.key.width = NULL, legend.text = element_text(size = rel(0.8)),
legend.text.align = NULL, legend.title = element_text(hjust = 0),
legend.title.align = NULL, legend.position = "right",
legend.direction = NULL, legend.justification = "center",
legend.box = NULL, legend.box.margin = margin(0, 0, 0,
0, "cm"), legend.box.background = element_blank(),
legend.box.spacing = unit(2 * half_line, "pt"), panel.background = element_rect(fill = "grey92",
colour = NA), panel.border = element_blank(), panel.grid = element_line(colour = "white"),
panel.grid.minor = element_line(size = rel(0.5)), panel.spacing = unit(half_line,
"pt"), panel.spacing.x = NULL, panel.spacing.y = NULL,
panel.ontop = FALSE, strip.background = element_rect(fill = "grey85",
colour = NA), strip.text = element_text(colour = "grey10",
size = rel(0.8), margin = margin(0.8 * half_line,
0.8 * half_line, 0.8 * half_line, 0.8 * half_line)),
strip.text.x = NULL, strip.text.y = element_text(angle = -90),
strip.placement = "inside", strip.placement.x = NULL,
strip.placement.y = NULL, strip.switch.pad.grid = unit(half_line/2,
"pt"), strip.switch.pad.wrap = unit(half_line/2,
"pt"), plot.background = element_rect(colour = "white"),
plot.title = element_text(size = rel(1.2), hjust = 0,
vjust = 1, margin = margin(b = half_line)), plot.subtitle = element_text(hjust = 0,
vjust = 1, margin = margin(b = half_line)), plot.caption = element_text(size = rel(0.8),
hjust = 1, vjust = 1, margin = margin(t = half_line)),
plot.tag = element_text(size = rel(1.2), hjust = 0.5,
vjust = 0.5), plot.tag.position = "topleft", plot.margin = margin(half_line,
half_line, half_line, half_line), complete = TRUE)
}
<bytecode: 0x7fdfc8f10b88>
<environment: namespace:ggplot2>
devtools::session_info()
details
## ─ Session info ───────────────────────────────────────────────────────────────
## setting value
## version R version 3.6.1 (2019-07-05)
## os macOS Catalina 10.15.5
## system x86_64, darwin15.6.0
## ui X11
## language (EN)
## collate en_US.UTF-8
## ctype en_US.UTF-8
## tz Asia/Shanghai
## date 2020-07-06
##
## ─ Packages ───────────────────────────────────────────────────────────────────
## package * version date lib source
## assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.6.0)
## backports 1.1.4 2019-04-10 [1] CRAN (R 3.6.0)
## callr 3.3.2 2019-09-22 [1] CRAN (R 3.6.0)
## cli 1.1.0 2019-03-19 [1] CRAN (R 3.6.0)
## colorspace 1.4-1 2019-03-18 [1] CRAN (R 3.6.0)
## crayon 1.3.4 2017-09-16 [1] CRAN (R 3.6.0)
## desc 1.2.0 2018-05-01 [1] CRAN (R 3.6.0)
## devtools 2.2.2 2020-02-17 [1] CRAN (R 3.6.0)
## digest 0.6.20 2019-07-04 [1] CRAN (R 3.6.0)
## dplyr 0.8.3 2019-07-04 [1] CRAN (R 3.6.0)
## ellipsis 0.3.0 2019-09-20 [1] CRAN (R 3.6.0)
## evaluate 0.14 2019-05-28 [1] CRAN (R 3.6.0)
## fs 1.3.1 2019-05-06 [1] CRAN (R 3.6.0)
## ggplot2 * 3.2.1 2019-08-10 [1] CRAN (R 3.6.0)
## glue 1.3.1 2019-03-12 [1] CRAN (R 3.6.0)
## gtable 0.3.0 2019-03-25 [1] CRAN (R 3.6.0)
## htmltools 0.3.6 2017-04-28 [1] CRAN (R 3.6.0)
## knitr 1.28 2020-02-06 [1] CRAN (R 3.6.0)
## labeling 0.3 2014-08-23 [1] CRAN (R 3.6.0)
## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 3.6.0)
## magick 2.3 2020-01-24 [1] CRAN (R 3.6.0)
## magrittr 1.5 2014-11-22 [1] CRAN (R 3.6.0)
## memoise 1.1.0 2017-04-21 [1] CRAN (R 3.6.0)
## munsell 0.5.0 2018-06-12 [1] CRAN (R 3.6.0)
## pillar 1.4.2 2019-06-29 [1] CRAN (R 3.6.0)
## pkgbuild 1.0.6 2019-10-09 [1] CRAN (R 3.6.0)
## pkgconfig 2.0.2 2018-08-16 [1] CRAN (R 3.6.0)
## pkgload 1.0.2 2018-10-29 [1] CRAN (R 3.6.0)
## plyr 1.8.4 2016-06-08 [1] CRAN (R 3.6.0)
## png 0.1-7 2013-12-03 [1] CRAN (R 3.6.0)
## prettyunits 1.0.2 2015-07-13 [1] CRAN (R 3.6.0)
## processx 3.4.1 2019-07-18 [1] CRAN (R 3.6.0)
## ps 1.3.0 2018-12-21 [1] CRAN (R 3.6.0)
## purrr 0.3.3 2019-10-18 [1] CRAN (R 3.6.0)
## R6 2.4.0 2019-02-14 [1] CRAN (R 3.6.0)
## Rcpp 1.0.2 2019-07-25 [1] CRAN (R 3.6.0)
## remotes 2.1.1 2020-02-15 [1] CRAN (R 3.6.0)
## reshape2 1.4.3 2017-12-11 [1] CRAN (R 3.6.0)
## rlang 0.4.5 2020-03-01 [1] CRAN (R 3.6.0)
## rmarkdown 2.2 2020-05-31 [1] CRAN (R 3.6.1)
## rprojroot 1.3-2 2018-01-03 [1] CRAN (R 3.6.0)
## scales 1.0.0 2018-08-09 [1] CRAN (R 3.6.0)
## sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.6.0)
## stringi 1.4.3 2019-03-12 [1] CRAN (R 3.6.0)
## stringr 1.4.0 2019-02-10 [1] CRAN (R 3.6.0)
## testthat 2.3.2 2020-03-02 [1] CRAN (R 3.6.0)
## tibble 2.1.3 2019-06-06 [1] CRAN (R 3.6.0)
## tidyselect 0.2.5 2018-10-11 [1] CRAN (R 3.6.0)
## usethis 1.5.1 2019-07-04 [1] CRAN (R 3.6.0)
## withr 2.1.2 2018-03-15 [1] CRAN (R 3.6.0)
## xfun 0.10 2019-10-01 [1] CRAN (R 3.6.0)
## yaml 2.2.0 2018-07-25 [1] CRAN (R 3.6.0)
##
## [1] /Library/Frameworks/R.framework/Versions/3.6/Resources/library